<?php
namespace App\Controller;

use Hyperf\Di\Annotation\Inject;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\Parallel;
use Hyperf\Utils\WaitGroup;
use Swoole\Coroutine\Channel;


/**
 * @AutoController()
 * Class Co1Controller
 * @package App\Controller
 */
class Co1Controller
{
    /**
     * @Inject()
     * @var ClientFactory
     */
    private $clientFactory;

    public function sleep(RequestInterface $request) {
        $seconds = $request->query('seconds', 1);
        sleep($seconds);
        return $seconds;
    }

    private static $_URL = '127.0.0.1:9501/co1/sleep?seconds=2';

    // 不使用协程的请求
    public function test(){
        $client = $this->clientFactory->create();
        $res = $client->get(self::$_URL);
        return $res;
    }

    // 使用协程的请求  Channel
    public function test1(){
        $channel = new Channel();
        co(function () use($channel) {
           $client = $this->clientFactory->create();
           $client->get(self::$_URL);
           $channel->push('fuck');
        });
        co(function () use($channel) {
            $client = $this->clientFactory->create();
            $client->get(self::$_URL);
            $channel->push('rubbish');
        });
        $result[] = $channel->pop();
        $result[] = $channel->pop();
        return $result;
    }

    // 使用协程的请求 WaitGroup
    public function test2(RequestInterface $request){
        $num = $request->query('num',2);
        $wg = new WaitGroup();
        $result = [];
        // 有几个协程就写几个
        $wg->add($num);
        for ($i=0;$i<$num;$i++){
            co(function () use($wg, &$result, $i){
                $client = $this->clientFactory->create();
                $client->get(self::$_URL);
                $result[] = 'rubbish-'.$i;
                $wg->done();
            });
        }
        $wg->wait();
        return $result;
    }

    // 使用协程的请求 Parallel
    public function test3(RequestInterface $request){
        $num = $request->query('num',2);
        $parallel = new Parallel();
        for ($i=0;$i<$num;$i++) {
            $parallel->add(function () use ($i) {
                $client = $this->clientFactory->create();
                $client->get(self::$_URL);
                return 'fuck-' . $i;
            },'foo-'.$i);
        }
        $result = $parallel->wait();
        return $result;
    }

    // 使用协程的请求 全局 Parallel
    public function test4(){
        $result = parallel([
            function () {
                $client = $this->clientFactory->create();
                $client->get(self::$_URL);
                return 'rubbish';
            },
            function () {
                $client = $this->clientFactory->create();
                $client->get(self::$_URL);
                return 'fuck';
            },
        ]);
        return $result;
    }
}